﻿#include "CServerMainModule.h"
#include "../game/MsgID.h"
#include "../game/MsgStruct.h"
#include "../basic/CSocketMisc.h"
#include "CTotrisGame.h"

#include <string.h>
#include <stdio.h>
#include <time.h>

#define SERVER_DEBUG(fmt, ...) printf("%s:%d fn:%s " fmt "\n", strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__);

static int send_msg_to_all_users(CServerMainModule* thes, CMsg* msg) {
	CMap* m = &thes->users_map;
	CMapIterator it;

	construct_cmap_iterator(&it);
	for (it.ptr = m->begin(m); it.ptr != m->end(m); it.next(&it)) {
		CUser* u = (CUser*)GET_VALUE_FROM_IT(it);
		if (!u) {
			continue;
		}
		u->send_socket_msg(u, msg);
	}
	return 0;
}

static CSparePart* get_new_spare_part(int some_input) {
	int alloc_len = sizeof(CSparePart);
	CSparePart* spare_part = (CSparePart*)malloc(alloc_len);

	memset(spare_part, 0, alloc_len);

	spare_part->atom_cnt = 4;
	switch (rand() % 19) {
	case 0:
		SERVER_DEBUG("type:\n****");
		spare_part->atoms[0].coord.x = 0; spare_part->atoms[0].coord.y = 0; spare_part->atoms[0].data = 1;
		spare_part->atoms[1].coord.x = 1; spare_part->atoms[1].coord.y = 0; spare_part->atoms[1].data = 1;
		spare_part->atoms[2].coord.x = 2; spare_part->atoms[2].coord.y = 0; spare_part->atoms[2].data = 1;
		spare_part->atoms[3].coord.x = 3; spare_part->atoms[3].coord.y = 0; spare_part->atoms[3].data = 1;
		break;
	case 1:
		SERVER_DEBUG("type:\n*\n*\n*\n*");
		spare_part->atoms[0].coord.x = 0; spare_part->atoms[0].coord.y = 0; spare_part->atoms[0].data = 1;
		spare_part->atoms[1].coord.x = 0; spare_part->atoms[1].coord.y = 1; spare_part->atoms[1].data = 1;
		spare_part->atoms[2].coord.x = 0; spare_part->atoms[2].coord.y = 2; spare_part->atoms[2].data = 1;
		spare_part->atoms[3].coord.x = 0; spare_part->atoms[3].coord.y = 3; spare_part->atoms[3].data = 1;
		break;
	case 2:
		SERVER_DEBUG("type:\n**\n **");
		spare_part->atoms[0].coord.x = 0; spare_part->atoms[0].coord.y = 0; spare_part->atoms[0].data = 1;
		spare_part->atoms[1].coord.x = 1; spare_part->atoms[1].coord.y = 0; spare_part->atoms[1].data = 1;
		spare_part->atoms[2].coord.x = 1; spare_part->atoms[2].coord.y = 1; spare_part->atoms[2].data = 1;
		spare_part->atoms[3].coord.x = 2; spare_part->atoms[3].coord.y = 1; spare_part->atoms[3].data = 1;
		break;
	case 3:
		SERVER_DEBUG("type:\n *\n**\n*");
		spare_part->atoms[0].coord.x = 0; spare_part->atoms[0].coord.y = 1; spare_part->atoms[0].data = 1;
		spare_part->atoms[1].coord.x = 0; spare_part->atoms[1].coord.y = 2; spare_part->atoms[1].data = 1;
		spare_part->atoms[2].coord.x = 1; spare_part->atoms[2].coord.y = 0; spare_part->atoms[2].data = 1;
		spare_part->atoms[3].coord.x = 1; spare_part->atoms[3].coord.y = 1; spare_part->atoms[3].data = 1;
		break;
	case 4:
		SERVER_DEBUG("type:\n **\n**");
		spare_part->atoms[0].coord.x = 0; spare_part->atoms[0].coord.y = 1; spare_part->atoms[0].data = 1;
		spare_part->atoms[1].coord.x = 1; spare_part->atoms[1].coord.y = 0; spare_part->atoms[1].data = 1;
		spare_part->atoms[2].coord.x = 1; spare_part->atoms[2].coord.y = 1; spare_part->atoms[2].data = 1;
		spare_part->atoms[3].coord.x = 2; spare_part->atoms[3].coord.y = 0; spare_part->atoms[3].data = 1;
		break;
	case 5:
		SERVER_DEBUG("type:\n*\n**\n *");
		spare_part->atoms[0].coord.x = 0; spare_part->atoms[0].coord.y = 0; spare_part->atoms[0].data = 1;
		spare_part->atoms[1].coord.x = 0; spare_part->atoms[1].coord.y = 1; spare_part->atoms[1].data = 1;
		spare_part->atoms[2].coord.x = 1; spare_part->atoms[2].coord.y = 1; spare_part->atoms[2].data = 1;
		spare_part->atoms[3].coord.x = 1; spare_part->atoms[3].coord.y = 2; spare_part->atoms[3].data = 1;
		break;
	case 6:
		SERVER_DEBUG("type:\n**\n**");
		spare_part->atoms[0].coord.x = 0; spare_part->atoms[0].coord.y = 0; spare_part->atoms[0].data = 1;
		spare_part->atoms[1].coord.x = 0; spare_part->atoms[1].coord.y = 1; spare_part->atoms[1].data = 1;
		spare_part->atoms[2].coord.x = 1; spare_part->atoms[2].coord.y = 0; spare_part->atoms[2].data = 1;
		spare_part->atoms[3].coord.x = 1; spare_part->atoms[3].coord.y = 1; spare_part->atoms[3].data = 1;
		break;
	case 7:
		SERVER_DEBUG("type:\n*\n**\n*");
		spare_part->atoms[0].coord.x = 0; spare_part->atoms[0].coord.y = 0; spare_part->atoms[0].data = 1;
		spare_part->atoms[1].coord.x = 0; spare_part->atoms[1].coord.y = 1; spare_part->atoms[1].data = 1;
		spare_part->atoms[2].coord.x = 0; spare_part->atoms[2].coord.y = 2; spare_part->atoms[2].data = 1;
		spare_part->atoms[3].coord.x = 1; spare_part->atoms[3].coord.y = 1; spare_part->atoms[3].data = 1;
		break;
	case 8:
		SERVER_DEBUG("type:\n *\n***");
		spare_part->atoms[0].coord.x = 0; spare_part->atoms[0].coord.y = 1; spare_part->atoms[0].data = 1;
		spare_part->atoms[1].coord.x = 1; spare_part->atoms[1].coord.y = 0; spare_part->atoms[1].data = 1;
		spare_part->atoms[2].coord.x = 1; spare_part->atoms[2].coord.y = 1; spare_part->atoms[2].data = 1;
		spare_part->atoms[3].coord.x = 2; spare_part->atoms[3].coord.y = 1; spare_part->atoms[3].data = 1;
		break;
	case 9:
		SERVER_DEBUG("type:\n *\n**\n *");
		spare_part->atoms[0].coord.x = 0; spare_part->atoms[0].coord.y = 1; spare_part->atoms[0].data = 1;
		spare_part->atoms[1].coord.x = 1; spare_part->atoms[1].coord.y = 0; spare_part->atoms[1].data = 1;
		spare_part->atoms[2].coord.x = 1; spare_part->atoms[2].coord.y = 1; spare_part->atoms[2].data = 1;
		spare_part->atoms[3].coord.x = 1; spare_part->atoms[3].coord.y = 2; spare_part->atoms[3].data = 1;
		break;
	case 10:
		SERVER_DEBUG("type:\n***\n *");
		spare_part->atoms[0].coord.x = 0; spare_part->atoms[0].coord.y = 0; spare_part->atoms[0].data = 1;
		spare_part->atoms[1].coord.x = 1; spare_part->atoms[1].coord.y = 0; spare_part->atoms[1].data = 1;
		spare_part->atoms[2].coord.x = 1; spare_part->atoms[2].coord.y = 1; spare_part->atoms[2].data = 1;
		spare_part->atoms[3].coord.x = 2; spare_part->atoms[3].coord.y = 0; spare_part->atoms[3].data = 1;
		break;
	case 11:
		SERVER_DEBUG("type:\n*\n*\n**");
		spare_part->atoms[0].coord.x = 0; spare_part->atoms[0].coord.y = 0; spare_part->atoms[0].data = 1;
		spare_part->atoms[1].coord.x = 0; spare_part->atoms[1].coord.y = 1; spare_part->atoms[1].data = 1;
		spare_part->atoms[2].coord.x = 0; spare_part->atoms[2].coord.y = 2; spare_part->atoms[2].data = 1;
		spare_part->atoms[3].coord.x = 1; spare_part->atoms[3].coord.y = 2; spare_part->atoms[3].data = 1;
		break;
	case 12:
		SERVER_DEBUG("type:\n  *\n***");
		spare_part->atoms[0].coord.x = 0; spare_part->atoms[0].coord.y = 1; spare_part->atoms[0].data = 1;
		spare_part->atoms[1].coord.x = 1; spare_part->atoms[1].coord.y = 1; spare_part->atoms[1].data = 1;
		spare_part->atoms[2].coord.x = 2; spare_part->atoms[2].coord.y = 0; spare_part->atoms[2].data = 1;
		spare_part->atoms[3].coord.x = 2; spare_part->atoms[3].coord.y = 1; spare_part->atoms[3].data = 1;
		break;
	case 13:
		SERVER_DEBUG("type:\n**\n *\n *");
		spare_part->atoms[0].coord.x = 0; spare_part->atoms[0].coord.y = 0; spare_part->atoms[0].data = 1;
		spare_part->atoms[1].coord.x = 1; spare_part->atoms[1].coord.y = 0; spare_part->atoms[1].data = 1;
		spare_part->atoms[2].coord.x = 1; spare_part->atoms[2].coord.y = 1; spare_part->atoms[2].data = 1;
		spare_part->atoms[3].coord.x = 1; spare_part->atoms[3].coord.y = 2; spare_part->atoms[3].data = 1;
		break;
	case 14:
		SERVER_DEBUG("type:\n***\n*");
		spare_part->atoms[0].coord.x = 0; spare_part->atoms[0].coord.y = 0; spare_part->atoms[0].data = 1;
		spare_part->atoms[1].coord.x = 0; spare_part->atoms[1].coord.y = 1; spare_part->atoms[1].data = 1;
		spare_part->atoms[2].coord.x = 1; spare_part->atoms[2].coord.y = 0; spare_part->atoms[2].data = 1;
		spare_part->atoms[3].coord.x = 2; spare_part->atoms[3].coord.y = 0; spare_part->atoms[3].data = 1;
		break;
	case 15:
		SERVER_DEBUG("type:\n *\n *\n**");
		spare_part->atoms[0].coord.x = 0; spare_part->atoms[0].coord.y = 2; spare_part->atoms[0].data = 1;
		spare_part->atoms[1].coord.x = 1; spare_part->atoms[1].coord.y = 0; spare_part->atoms[1].data = 1;
		spare_part->atoms[2].coord.x = 1; spare_part->atoms[2].coord.y = 1; spare_part->atoms[2].data = 1;
		spare_part->atoms[3].coord.x = 1; spare_part->atoms[3].coord.y = 2; spare_part->atoms[3].data = 1;
		break;
	case 16:
		SERVER_DEBUG("type:\n***\n  *");
		spare_part->atoms[0].coord.x = 0; spare_part->atoms[0].coord.y = 0; spare_part->atoms[0].data = 1;
		spare_part->atoms[1].coord.x = 1; spare_part->atoms[1].coord.y = 0; spare_part->atoms[1].data = 1;
		spare_part->atoms[2].coord.x = 2; spare_part->atoms[2].coord.y = 0; spare_part->atoms[2].data = 1;
		spare_part->atoms[3].coord.x = 2; spare_part->atoms[3].coord.y = 1; spare_part->atoms[3].data = 1;
		break;
	case 17:
		SERVER_DEBUG("type:\n**\n*\n*");
		spare_part->atoms[0].coord.x = 0; spare_part->atoms[0].coord.y = 0; spare_part->atoms[0].data = 1;
		spare_part->atoms[1].coord.x = 0; spare_part->atoms[1].coord.y = 1; spare_part->atoms[1].data = 1;
		spare_part->atoms[2].coord.x = 0; spare_part->atoms[2].coord.y = 2; spare_part->atoms[2].data = 1;
		spare_part->atoms[3].coord.x = 1; spare_part->atoms[3].coord.y = 0; spare_part->atoms[3].data = 1;
		break;
	case 18:
		SERVER_DEBUG("type:\n*\n***");
		spare_part->atoms[0].coord.x = 0; spare_part->atoms[0].coord.y = 0; spare_part->atoms[0].data = 1;
		spare_part->atoms[1].coord.x = 0; spare_part->atoms[1].coord.y = 1; spare_part->atoms[1].data = 1;
		spare_part->atoms[2].coord.x = 1; spare_part->atoms[2].coord.y = 1; spare_part->atoms[2].data = 1;
		spare_part->atoms[3].coord.x = 2; spare_part->atoms[3].coord.y = 1; spare_part->atoms[3].data = 1;
		break;
	default:
		SERVER_DEBUG("error default!!");
		return 0;
	}
	return spare_part;
}

static int ON_MODULE_MSG(CServerMainModule, MSG_ID_TEST_REQ) {
	char* data = (char*)msg + sizeof(CMsg);
	ST_TEST_RES res = {{MSG_ID_TEST_RES, 1}, 0};

	SERVER_DEBUG("data=%d", data[0]);
	res.data[0] = data[0] + 1;
	thes->send_msg_to_all_users(thes, &res.msg);
	return 0;
}

static int ON_MODULE_MSG(CServerMainModule, MSG_ID_NEW_CONNECT_REQ) {
	ST_NEW_CONNECT_REQ* new_c = (ST_NEW_CONNECT_REQ*)msg;
	ST_NEW_CONNECT_RES res = {{MSG_ID_NEW_CONNECT_RES, sizeof(res) - sizeof(CMsg)}, 0};
	static int new_user_id = 0;
	CMap* m = &thes->users_map;
	CUser* new_u = (CUser*)malloc(sizeof(CUser));
	ST_NOTIFY_NEW_USER_ADDED notify = {{MSG_ID_NOTIFY_NEW_USER_ADDED, sizeof(notify) - sizeof(CMsg)}, 0};
	CMapIterator it;

	SERVER_DEBUG("new sock=0x%X", new_c->sock);
	construct_user(new_u, ++new_user_id, new_c->sock);

	//notify this new user to all user, that was connected
	notify.user_id = new_user_id;
	thes->send_msg_to_all_users(thes, &notify.msg);

	//response
	res.user_id = new_user_id;
	res.game_user_count = thes->game_user_count;
	new_u->send_socket_msg(new_u, &res.msg);

	//notify all connected user to this new user
	construct_cmap_iterator(&it);
	for (it.ptr = m->begin(m); it.ptr != m->end(m); it.next(&it)) {
		CUser* u = (CUser*)GET_VALUE_FROM_IT(it);
		if (!u) {
			continue;
		}
		notify.user_id = u->user_id;
		new_u->send_socket_msg(new_u, &notify.msg);
	}

	//add user
	m->insert(m, (void*)new_user_id, (void*)new_u);
	return 0;
}

static int ON_MODULE_MSG(CServerMainModule, MSG_ID_USR_READY_REQ) {
	ST_USR_READY_REQ* req = (ST_USR_READY_REQ*)msg;
	CMap* m = &thes->users_map;
	CUser* u = m->find(m, (void*)req->user_id);
	ST_USR_READY_RES res = {{MSG_ID_USR_READY_RES, sizeof(res) - sizeof(CMsg)}, 0};

	SERVER_DEBUG("user_id=%d", req->user_id);
	if (!u) {
		SERVER_DEBUG("find user error! user_id=%d", req->user_id);
		return -1;
	}
	u->st = USER_ST_READY;
	res.user_id = u->user_id;
	thes->send_msg_to_all_users(thes, &res.msg);

	//game start check
	if (thes->game_user_count == m->list.cnt) {
		ST_GAMESTART_CMD game_start = {{MSG_ID_GAMESTART_CMD, 0}};
		ST_USER_FIRST_NEXT first_n = {{MSG_ID_USER_FIRST_NEXT, sizeof(ST_USER_FIRST_NEXT) - sizeof(CMsg)}, 0};
		ST_USER_NEW_SPAREPART_NEXT new_n = {{MSG_ID_USER_NEW_SPAREPART_NEXT, sizeof(ST_USER_NEW_SPAREPART_NEXT) - sizeof(CMsg)}, 0};
		CMap* m = &thes->users_map;
		CMapIterator it;

		SERVER_DEBUG("game started!");
		thes->send_msg_to_all_users(thes, &game_start.msg);

		construct_cmap_iterator(&it);
		for (it.ptr = m->begin(m); it.ptr != m->end(m); it.next(&it)) {
			CUser* u = (CUser*)GET_VALUE_FROM_IT(it);
			if (!u) {
				continue;
			}
			free(u->next);
			u->next = get_new_spare_part(0);
			first_n.user_id = u->user_id;
			memcpy(&first_n.spare_part, u->next, sizeof(first_n.spare_part));
			thes->send_msg_to_all_users(thes, &first_n.msg);


			//next new spare part
			free(u->current);
			u->current = u->next;
			u->current->origin.x = (u->user_id - 1) * 16 + 8;
			u->current->origin.y = 0;
			SERVER_DEBUG("user(%d) current spare part is refreshed. origin[%d, %d]",u->user_id, u->current->origin.x, u->current->origin.y);

			u->next = get_new_spare_part(0);
			new_n.user_id = u->user_id;
			memcpy(&new_n.spare_part, u->next, sizeof(new_n.spare_part));
			thes->send_msg_to_all_users(thes, &new_n.msg);
		}
	}
	return 0;
}

static int server_do_pile(CServerMainModule* thes, CMsg* msg) {
	ST_KEY_PRESS_REQ* req = (ST_KEY_PRESS_REQ*)msg;
	CMap* m = &thes->users_map;
	CUser* operator_user = m->find(m, (void*)req->user_id);
	ST_DO_PILE_CMD cmd = {{MSG_ID_DO_PILE_CMD, sizeof(cmd) - sizeof(CMsg)}, 0};
	ST_USER_FIRST_NEXT n = {{MSG_ID_USER_NEW_SPAREPART_NEXT, sizeof(ST_USER_FIRST_NEXT) - sizeof(CMsg)}, 0};
	int full_cnt = 0;
	char full_row_num[ITEM_HEIGHT_COUNT] = {0};
	ST_ERASE_FULL_ROW_CMD erase_cmd = {{MSG_ID_ERASE_FULL_ROW_CMD, sizeof(erase_cmd) - sizeof(CMsg)}, 0};

	do_pile(operator_user->current, thes->piles);

	//sync client
	cmd.user_id = req->user_id;
	thes->send_msg_to_all_users(thes, &cmd.msg);

	//check full
	if (TOS_YES == is_have_full_row(thes->piles, erase_cmd.which_row, &erase_cmd.row_cnt)) {
		int i = 0;
		SERVER_DEBUG("row_cnt=%d", erase_cmd.row_cnt);

		for (i = 0; i < erase_cmd.row_cnt; ++i) {
			do_erase_full_row(thes->piles, erase_cmd.which_row[i]);
		}
		thes->send_msg_to_all_users(thes, &erase_cmd.msg);
	}

	//next new spare part
	free(operator_user->current);
	operator_user->current = operator_user->next;
	operator_user->current->origin.x = (operator_user->user_id - 1) * 16 + 8;
	operator_user->current->origin.y = 0;
	SERVER_DEBUG("user(%d) current spare part is refreshed. origin[%d, %d]", operator_user->user_id, operator_user->current->origin.x, operator_user->current->origin.y);

	operator_user->next = get_new_spare_part(0);
	n.user_id = operator_user->user_id;
	memcpy(&n.spare_part, operator_user->next, sizeof(n.spare_part));
	thes->send_msg_to_all_users(thes, &n.msg);
	return 0;
}

static int ON_MODULE_MSG(CServerMainModule, MSG_ID_KEY_PRESS_REQ) {
	ST_KEY_PRESS_REQ* req = (ST_KEY_PRESS_REQ*)msg;
    CMapIterator it;
	CMap* m = &thes->users_map;
	CUser* operator_user = m->find(m, (void*)req->user_id);
	CSparePart* clone = 0;
	ST_KEY_PRESS_RES res = {{MSG_ID_KEY_PRESS_RES, sizeof(res) - sizeof(CMsg)}, 0};
	int i = 0;

	SERVER_DEBUG("user_id=%d which_key=%d", req->user_id, req->which_key);
	if (!operator_user) {
		SERVER_DEBUG("find user error! user_id=%d", req->user_id);
		return -1;
	}
    
    clone = spare_part_clone_of(operator_user->current);
    switch(req->which_key) {
    case TOS_LEFTKEY:
        spare_part_move_left(clone);
        break;
    case TOS_RIGHTKEY:
        spare_part_move_right(clone);
        break;
    case TOS_DOWNKEY:
		spare_part_move_down(clone);
		if (TOS_YES == is_need_pile(clone, thes->piles)) {
			free(clone);
			server_do_pile(thes, msg);
			return 0;
		}
		break;
    case TOS_UPKEY:
        spare_part_rotate(clone);
        break;
    default:
        return -2;
    }
    if(clone->origin.x < 0) { //[0, 31]
		SERVER_DEBUG("user_id=%d reach border -> invalid operation x=%d", operator_user->user_id, clone->origin.x);
		free(clone);        
        return -3;
    }
	for (i = 0; i < clone->atom_cnt; ++i) {
		if (clone->origin.x + clone->atoms[i].coord.x >= ITEM_WIDTH_COUNT || clone->origin.y + clone->atoms[i].coord.y >= ITEM_HEIGHT_COUNT) {
			SERVER_DEBUG("user_id=%d reach border -> invalid operation. [%d, %d]", operator_user->user_id, clone->origin.x, clone->origin.y);
			free(clone);
			return -3;
		}
	}

	construct_cmap_iterator(&it);
	for (it.ptr = m->begin(m); it.ptr != m->end(m); it.next(&it)) {
		CUser* u = (CUser*)GET_VALUE_FROM_IT(it);
		if (!u || u->user_id == operator_user->user_id) {
			continue;
		}
        if(TOS_OVERLAP == is_overlap_spare_part(clone, u->current)) {
            SERVER_DEBUG("operator user_id=%d and user_id=%d is overlaped -> invalid operation.", operator_user->user_id, u->user_id);
			free(clone);
			return -4;
        }
	}

	if (TOS_OVERLAP == is_overlap_piles(clone, thes->piles)) {
		SERVER_DEBUG("operator user_id=%d and piles is overlaped -> invalid operation[leftward]", operator_user->user_id);
		free(clone);
		return -5;
	}
	free(operator_user->current);
	operator_user->current = clone;
	SERVER_DEBUG("u[%d] after key action origin[%d, %d]", operator_user->user_id, operator_user->current->origin.x, operator_user->current->origin.y);
	SERVER_DEBUG("data[%d, %d][%d, %d][%d, %d][%d, %d]", operator_user->current->atoms[0].coord.x, operator_user->current->atoms[0].coord.y, 
		operator_user->current->atoms[1].coord.x, operator_user->current->atoms[1].coord.y, 
		operator_user->current->atoms[2].coord.x, operator_user->current->atoms[2].coord.y, 
		operator_user->current->atoms[3].coord.x, operator_user->current->atoms[3].coord.y);
	
	//sync client
	res.user_id = operator_user->user_id;
	res.which_key = req->which_key;
	thes->send_msg_to_all_users(thes, &res.msg);
    return 0;
}

static int cserver_main_reg_func_on_msgid(CModule* thes) {
	REG_MODULE_MSG_FUNC(CServerMainModule, thes, MSG_ID_TEST_REQ);
	REG_MODULE_MSG_FUNC(CServerMainModule, thes, MSG_ID_NEW_CONNECT_REQ);
	REG_MODULE_MSG_FUNC(CServerMainModule, thes, MSG_ID_USR_READY_REQ);
	REG_MODULE_MSG_FUNC(CServerMainModule, thes, MSG_ID_KEY_PRESS_REQ);
	return 0;
}

int construct_server_main(CServerMainModule* thes, const char* module_name) {
	srand((unsigned int)time(NULL));
	construct_module(&thes->parent, module_name);
	construct_map(&thes->users_map, INT_KEY_CMP_FUNC);
	thes->game_user_count = 2;
	memset(thes->piles, 0, sizeof(thes->piles));

	thes->send_msg_to_all_users = send_msg_to_all_users;
	cserver_main_reg_func_on_msgid(AS_MODULE(thes));
	AS_MODULE(thes)->run(AS_MODULE(thes), USE_DEFAULT_MODULE_ENTRY);
	return 0;
}

